using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using net_work.Data.Entity.Sys;

namespace net_work.Common.Utils;

public static class JWTUtils
{
    private static readonly IConfiguration Configuration = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json")
        .AddJsonFile("appsettings.Development.json")
        .AddEnvironmentVariables()
        .Build();

    /// <summary>
    /// 生成 Access Token
    /// </summary>
    /// <param name="user">用户信息</param>
    /// <returns>Access Token</returns>
    /// <exception cref="InvalidOperationException">配置文件读取异常</exception>
    public static string GenerateToken(User user)
    {
        var jwtSettings = Configuration.GetSection("JwtSettings");
        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()), // 用户ID
            new Claim(JwtRegisteredClaimNames.Name, user.UserAccount), // 用户名
            new Claim(ClaimTypes.Role, user.UserRole), // 角色
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), // Token唯一ID
            new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(),
                ClaimValueTypes.Integer64) // 签发时间
        };

        var key = new SymmetricSecurityKey(
            Encoding.UTF8.GetBytes(jwtSettings["Key"] ?? throw new InvalidOperationException()));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            issuer: jwtSettings["Issuer"],
            audience: jwtSettings["Audience"],
            claims: claims,
            expires: DateTime.UtcNow.AddMinutes(int.Parse(jwtSettings["AccessTokenExpiryMinutes"] ??
                                                          throw new InvalidOperationException())),
            signingCredentials: creds);

        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}